package at.ac.tuwien.swa.sparrow.web

import at.ac.tuwien.swa.sparrow.common.{TrackMetadata, Account, InvalidCredentialsException}
import at.ac.tuwien.swa.sparrow.server.persistence.{SongRecognitionRepository, AccountRepository}
import at.ac.tuwien.swa.sparrow.server.security.{Secured, SecurityContext}
import java.util.concurrent.atomic.AtomicLong
import javax.inject.Inject
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMethod._
import org.springframework.web.bind.annotation.{ResponseBody, RequestMapping}
import scala.Array
import scala.Some

@Controller
@RequestMapping(Array("/web"))
class WebController @Inject()(accountRepository: AccountRepository, songRepo: SongRecognitionRepository) {
	@RequestMapping(Array("/session"))
	@ResponseBody def sessionAccount() = {
		//if the current role is a user session, then it's okay otherwise not
		SecurityContext.getRole match {
			case o: UserSession => o
			case _ => null
		}
	}

	@RequestMapping(Array("/profile"))
	@Secured(classOf[UserSession])
	@ResponseBody def getProfile = {
		//load the data again from the repository
		SecurityContext.getRole match {
			case session: UserSession => accountRepository.findOne(session.id)
			case _ => null
		}
	}

	@RequestMapping(value = Array("/login"), method = Array(POST))
	@ResponseBody def login(username: String, password: String) {
		accountRepository findOne(username, password) match {
			case None => throw InvalidCredentialsException()
			case Some(a: Account) => SecurityContext.setRole(UserSession(a.id, a.username, "John", "Doe"))
		}
	}

	@RequestMapping(value = Array("/logout"), method = Array(POST))
	@ResponseBody def logout() {
		//just remove the role from security context
		SecurityContext.setRole(null)
	}

	@RequestMapping(value = Array("/register"), method = Array(POST))
	@ResponseBody def register(username: String, password: String, firstname: String, lastname: String) {
		accountRepository.save(Account(username, password, new AtomicLong(0)))
	}

	@RequestMapping(Array("/tracks"))
	@ResponseBody def getTrackStream: List[TrackMetadata] = {
		(songRepo findAll() groupBy (_.metadata)).toList.sortBy(-_._2.size) take 10 map (_._1)
	}
}

case class UserSession(id: Long, username: String, firstname: String, lastname: String)
